/**
  ******************************************************************************
  * File   : FLASH/operate_SPIM/SPIM/SPIM_test.c
  * Version: V1.2.3
  * Date   : 2020-08-15
  * Brief  : This file contains the function SPIM_test used to test ext.flash
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "bsp_spim.h"
#include "at32f4xx.h"  
#include "bsp.h"  

/** @addtogroup AT32F413_StdPeriph_Examples
  * @{
  */

/** @addtogroup FLASH_Operate_SPIM
  * @{
  */

/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Configures the ext.flash
  * @param  None
  * @retval None
  */
void FLASH_InitExtFlash(void)
{
  GPIO_InitType GPIO_InitStructure;
  
  /* Enable ext.flash GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO|RCC_APB2PERIPH_GPIOA|RCC_APB2PERIPH_GPIOB, ENABLE);
  
  /* Configure ext.flash pin */
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8;
  GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pins = GPIO_Pins_1|GPIO_Pins_6|GPIO_Pins_7|GPIO_Pins_10|GPIO_Pins_11;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /* Select PB10, PB11 as SPIF_TX and SPIF_RX */
  GPIO_PinsRemapConfig(GPIO_Remap_EXT_FLASH, ENABLE);
  GPIO_PinsRemapConfig(AFIO_MAP7_SPIF_1001, ENABLE);
  
  /* In this example, use on-board EN25QH128A as ext.flash */
  FLASH->B3SEL = FLASH_SPIM_TYPE2;
  
  /* Unlock the ext.flash program erase controller */  
  while (BIT_READ(FLASH->STS3, FLASH_STS_BSY));
  FLASH->FCKEY3 = FLASH_KEY1;
  FLASH->FCKEY3 = FLASH_KEY2;
  while (BIT_READ(FLASH->CTRL3, FLASH_CTRL_LCK));
  
  /* If the data written to ext.flash need to be scrambled, please specify the scrambled range */
  FLASH->DA = 0;
  
  return;
}



/*******************************************************************************
* @brief  bsp_spim_read
* \param[in] none
* \retval: none
*******************************************************************************/
uint8_t bsp_spim_read(uint32_t addr, uint32_t len, uint8_t *data)
{
    uint32_t *pdes = (uint32_t *)data;
    uint32_t *psrc;
    uint32_t index;
    
    psrc = (uint32_t *)(addr + SPIM_START_ADDR);
    
    for(index = 0; index < (len>>2); index++)
    {
        *pdes++ = *psrc++;
    }
    
    return 0;
}

/*******************************************************************************
* @brief  bsp_spim_read
* \param[in] none
* \retval: none
*******************************************************************************/
uint8_t bsp_spim_write(uint32_t addr, uint32_t len, uint8_t *data)
{
    uint32_t *pdat = (uint32_t *)data;
    uint32_t index;
    
    FLASH_UnlockBank3();
    
    addr += SPIM_START_ADDR;
    
    for(index = 0; index < len; index+=4)
    {
        FLASH_ProgramWord(addr + index, *pdat++);
    }
    
    FLASH_LockBank3();  
    
    if(FLASH->STS3 & FLASH_STS_PRGMFLR)
    {
        FLASH->STS3 |= FLASH_STS_PRGMFLR;
        return 1;
    }
    return 0;
}

/*******************************************************************************
* @brief  bsp_spim_read
* \param[in] none
* \retval: none
*******************************************************************************/
uint8_t bsp_spim_erase(uint32_t addr)
{
    addr += SPIM_START_ADDR;
    
    FLASH_UnlockBank3();
    
    FLASH_ErasePage(addr);
    
    FLASH_LockBank3();  
    
    if(FLASH->STS3 & FLASH_STS_PRGMFLR)
    {
        FLASH->STS3 |= FLASH_STS_PRGMFLR;
        return 1;
    }
    
    return 0;
}


/******************* (C) COPYRIGHT 2018 ArteryTek *****END OF FILE****/
